<html>
  <head>
	  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>i5ting_ztree_toc:es6</title>
		<link href="toc/style/github-bf51422f4bb36427d391e4b75a1daa083c2d840e.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/style/github2-d731afd4f624c99a4b19ad69f3083cd6d02b81d5.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/css/zTreeStyle/zTreeStyle.css" media="all" rel="stylesheet" type="text/css"/>
	  <style>
		pre {
		    counter-reset: line-numbering;
		    border: solid 1px #d9d9d9;
		    border-radius: 0;
		    background: #fff;
		    padding: 0;
		    line-height: 23px;
		    margin-bottom: 30px;
		    white-space: pre;
		    overflow-x: auto;
		    word-break: inherit;
		    word-wrap: inherit;
		}

		pre a::before {
		  content: counter(line-numbering);
		  counter-increment: line-numbering;
		  padding-right: 1em; /* space after numbers */
		  width: 25px;
		  text-align: right;
		  opacity: 0.7;
		  display: inline-block;
		  color: #aaa;
		  background: #eee;
		  margin-right: 16px;
		  padding: 2px 10px;
		  font-size: 13px;
		  -webkit-touch-callout: none;
		  -webkit-user-select: none;
		  -khtml-user-select: none;
		  -moz-user-select: none;
		  -ms-user-select: none;
		  user-select: none;
		}

		pre a:first-of-type::before {
		  padding-top: 10px;
		}

		pre a:last-of-type::before {
		  padding-bottom: 10px;
		}

		pre a:only-of-type::before {
		  padding: 10px;
		}

		.highlight { background-color: #ffffcc } /* RIGHT */
		</style>
  </head>
  <body>
	  <div>
				<div style='width:25%;'>
						<ul id="tree" class="ztree" style='width:100%'>

						</ul>
				</div>
        <div id='readme' style='width:70%;margin-left:20%;'>
          	<article class='markdown-body'>
            	<h1 id="-">基础语法增强</h1>
<h2 id="ecmascript6">ECMAScript6</h2>
<blockquote>
<p>ES6也称为ECMAScript2015，是2015年出版的javaScript国际新标准，
标准的制定者计划，以后每年发布一次标准，使用年份作为版本号，
ES6是在2015年发布的，所以又称为ECMAScript2015，2016年发布的标准即为ES7。</p>
</blockquote>
<h2 id="let-const">let与const</h2>
<blockquote>
<p>新的变量定义方式。</p>
</blockquote>
<h4 id="let">let</h4>
<ul>
<li>作用：<ul>
<li>替代var关键字定义变量</li>
</ul>
</li>
<li>特点：<ul>
<li>不允许重复声明</li>
<li>块级作用域</li>
<li>没有预解析</li>
<li>存在暂时性死区</li>
<li>全局变量不再是window属性</li>
</ul>
</li>
</ul>
<h4 id="const">const</h4>
<ul>
<li>作用：<ul>
<li>定义常量</li>
</ul>
</li>
<li>特点：<ul>
<li>不允许重复声明</li>
<li>块级作用域</li>
<li>没有预解析</li>
<li>存在暂时性死区</li>
<li>全局变量不再是window属性</li>
<li>定义时必须赋值，同时不允许修改</li>
</ul>
</li>
</ul>
<h4 id="-">特点演示</h4>
<ul>
<li><p>不允许重复声明</p>
<pre><code class="lang-javascript">// SyntaxError，在语法分析时就报错
let a = 10;  
let a = 20;
</code></pre>
<pre><code class="lang-javascript">function fn(arg) {
  let arg;
}
fn(10); // SyntaxError
</code></pre>
</li>
<li><p>块级作用域</p>
<pre><code class="lang-javascript">{
  let a = 10;
  console.log(a); // 10
}
console.log(a);  // ReferenceError
</code></pre>
</li>
<li><p>没有预解析</p>
<pre><code class="lang-javascript">console.log(a);  // ReferenceError
let a = 10;
</code></pre>
</li>
<li><p>存在暂时性死区</p>
<ul>
<li>即在某作用域内如果存在let、const声明的变量常量，</li>
<li>如果在声明前使用它们就报错，也不会从上级作用域中查找。<pre><code class="lang-javascript">let a = 10;
{
console.log(a);  // ReferenceError
let a = 20;
}
</code></pre>
</li>
</ul>
</li>
<li><p>全局变量不再是window属性</p>
<pre><code class="lang-javascript">let a 10;
console.log(a); // 10
console.log(window.a); // undefined
</code></pre>
</li>
<li><p>const定义常量时必须一起赋值</p>
<pre><code class="lang-javascript">const NAME;  // SyntaxError;
</code></pre>
</li>
<li><p>常量的值不允许修改</p>
<pre><code class="lang-javascript">const NAME = &#39;地球&#39;;
NAME = &#39;火星&#39;;  // TypeError
</code></pre>
</li>
</ul>
<h4 id="-">使用场景</h4>
<ul>
<li><p>防止变量污染</p>
<pre><code class="lang-javascript">let i = 10;
for(let i = 0; i &lt; 3; i++) {
  console.log(i);
}
console.log(i); // 10
</code></pre>
</li>
<li><p>帮助预防潜在错误</p>
<pre><code class="lang-javascript">console.log(a + b); // RefrenceError
let a = 10;
let b = 20;
</code></pre>
</li>
<li><p>常量特性</p>
<pre><code class="lang-javascript">const PI = 3.1415926;
PI = 2.1415926;  // TypeError
</code></pre>
</li>
</ul>
<h2 id="-">解构赋值</h2>
<blockquote>
<p>按照一定的模式，从数组和对象中提取值，然后对变量进行赋值</p>
</blockquote>
<h4 id="-">数组解构</h4>
<ul>
<li><p>完全解构</p>
<pre><code class="lang-javascript">let arr = [10, 20, 30];
let [ a, b, c ] = arr;
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
</code></pre>
</li>
<li><p>部分解构</p>
<pre><code class="lang-javascript">let [ a, , c ] = [10, 20, 30];
console.log(a); // 10
console.log(c); // 30
</code></pre>
</li>
<li><p>特殊值</p>
<pre><code class="lang-javascript">let [ a, b, c ] = [10, [ 20, 21, 22 ], {a: 1, b: 2}];
console.log(a); // 10
console.log(b); // [ 20, 21, 22 ]
console.log(c); // {a: 1, b: 2}
</code></pre>
</li>
<li><p>深层解构</p>
<pre><code class="lang-javascript">let [ a, [b1, b2] ] = [10, [ 20, 21, 22 ], 30];
console.log(a); // 10
console.log(b1); // 20
console.log(b2); // 21
</code></pre>
</li>
<li><p>解构缺失</p>
<pre><code class="lang-javascript">let [ a, b ] = [10];
console.log(a); // 10
console.log(b); // undefined
</code></pre>
</li>
<li><p>默认值</p>
<pre><code class="lang-javascript">let [ a = &#39;aa&#39;, b = &#39;bb&#39; ] = [10];
console.log(a); // 10
console.log(b); // bb
</code></pre>
</li>
</ul>
<h4 id="-">对象解构</h4>
<ul>
<li><p>完全解构</p>
<pre><code class="lang-javascript">let { a, b, c } = { a: 10, b: 20, c: 30 };
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
</code></pre>
</li>
<li><p>部分解构</p>
<pre><code class="lang-javascript">let { a, c } = { a: 10, b: 20, c: 30 };
console.log(a); // 10
console.log(c); // 30
</code></pre>
</li>
<li><p>特殊值</p>
<pre><code class="lang-javascript">let { a, b, c } = { a: 10, b: [20, 21, 22], c: { c1: 30, c2: 31 } };
console.log(a); // 10
console.log(b); // [20, 21, 22]
console.log(c); // { c1: 30, c2: 31 }
</code></pre>
</li>
<li><p>深层解构</p>
<pre><code class="lang-javascript">// 对象深层解构会有不足，浅层属性与深层属性只能选其一进行解构
let { a, b: [ b1, b2 ], c: { c1, c2 } } = { a: 10, b: [20, 21], c: { c1: 30, c2: 31 } };
console.log(a); // 10
console.log(b); // RefrenceError
console.log(b1); // 30
console.log(b2); // 30
console.log(b3); // 30
console.log(c); // RefrenceError
console.log(c1); // 30
console.log(c2); // 30
</code></pre>
</li>
<li><p>解构缺失</p>
<pre><code class="lang-javascript">let { a, b } = { a: 10 };
console.log(a); // 10
console.log(b); // undefined
</code></pre>
</li>
<li><p>默认值</p>
<pre><code class="lang-javascript">let { a = &#39;aa&#39;, b = &#39;bb&#39; } = { a: 10 };
console.log(a); // 10
console.log(b); // bb
</code></pre>
</li>
<li><p>重定变量名</p>
<pre><code class="lang-javascript">let { a: myA } = { a: 10 };
console.log(myA); // 10
console.log(a); // ReferenceError
</code></pre>
</li>
</ul>
<h4 id="-">使用场景</h4>
<ul>
<li><p>变量交换</p>
<pre><code class="lang-javascript">let a = 10, b = 20, c = 30;
[a, b, c] = [ b, c, a ];
console.log(a, b, c);
</code></pre>
</li>
<li><p>提取对象中值</p>
<pre><code class="lang-javascript">let ajaxResponseData = {
  code: 200,
  msg: &#39;成功&#39;,
  result: {
      name: &#39;车&#39;,
      info: &#39;各种车&#39;,
      list: [&#39;兰博基尼&#39;, &#39;法拉利&#39;]
  }
};
let { result: { info, list } } = ajaxResponseData;
console.log(info);
console.log(list);
</code></pre>
</li>
<li><p>函数返回多个值（本质还是提取对象中的值）</p>
<pre><code class="lang-javascript">function fn() {
  var obj = {};
  return {
      get: function(key){
          return obj[key];
      },
      set: function(key, val){
          obj[key] = val;
      }
  };
}
var { get, set } = fn();
set(&#39;fib&#39;, [1, 1, 2, 3, 5, 8, 13]);
console.log(get(&#39;fib&#39;));
</code></pre>
</li>
</ul>
<h2 id="-">``字符串</h2>
<blockquote>
<p>新的字符串定义方式。</p>
</blockquote>
<ul>
<li><p>多行字符串</p>
<pre><code class="lang-javascript">let str = `第一行第一行
  第二行第二行`;
console.log(str);
</code></pre>
</li>
<li><p>模版字符串</p>
<pre><code class="lang-javascript">// 可以访问变量、调用函数、及各种表达式运算
var mei = {
  name: &#39;小美&#39;,
  age: 16
};
let str = `${ mei.name }今年${ mei.age }了，
  还有${ 30 - mei.age }年他就30了`;
console.log(str);
</code></pre>
</li>
</ul>
<h2 id="-">运算符</h2>
<h4 id="-">...运算符 （扩展运算符、多值运算符）</h4>
<blockquote>
<p>多个值可包装成数组，也可解开真伪数组为多个值。</p>
</blockquote>
<ul>
<li><p>用于形参定义 - 可获取剩余参数为数组</p>
<pre><code class="lang-javascript">function fn(a, ...s) {
  console.log(s);
}
fn(1, 2, 3, 4, 5, 6);
</code></pre>
</li>
<li><p>用于函数调用 - 可解开数组依次传递(替代apply)</p>
<pre><code class="lang-javascript">let nums = [55, 33, 66, 11];
console.log(Math.min.apply(null, nums)) // 11
console.log(Math.min(...nums)) // 11
</code></pre>
</li>
<li><p>用于数组定义 - 可合并数组</p>
<pre><code class="lang-javascript">let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr3 = [7, 8, 9];
let arr4 = [ ...arr1, ...arr2, ...arr3 ];
console.log(arr4);
</code></pre>
</li>
<li><p>用于数组解构赋值 - 可用1个变量获取数组剩余值</p>
<pre><code class="lang-javascript">let arr = [ 11, 22, 33, 44 ];
let [ a, ...b ] = arr;
console.log(a, b);  // 11, [ 22, 33, 44 ]
</code></pre>
</li>
</ul>
<h2 id="-">函数</h2>
<h4 id="-">函数形参的定义</h4>
<ul>
<li><p>设置默认值</p>
<blockquote>
<p>具有默认值的形参最好定义在后面</p>
<pre><code class="lang-javascript">function fn(a = 10, b = 20) {
  console.log(a + b);
}
fn();
fn(100);
fn(100, 200);
</code></pre>
</blockquote>
</li>
<li><p>参数解构赋值</p>
<pre><code class="lang-javascript">function fn({a, b}) {
  console.log(a + b);
}
fn({a: 11, b: 22});
</code></pre>
</li>
<li><p>...形参语法</p>
<blockquote>
<ol>
<li>把函数剩余的参数存储到数组中</li>
</ol>
</blockquote>
</li>
<li>该语法定义的形参可以替代arguments</li>
<li>只有最后一个形参才能这样写<pre><code class="lang-javascript">function total(...nums) {
 return nums.reduce(function(prevResult, current) {
     return prevResult + current;
 });
}
total(11, 22, 33, 44);  // 110
</code></pre>
</li>
</ul>
<h4 id="-">箭头函数</h4>
<ul>
<li>简述：<ul>
<li>使用=&gt;定义函数。</li>
</ul>
</li>
<li>特点：<ul>
<li>this固定指向上级this，不再和调用方式有关</li>
<li>不能作为构造函数使用</li>
<li>不能使用arguments，可使用...语法代替</li>
</ul>
</li>
<li><p>语法：</p>
<ul>
<li>形参 =&gt; 代码体</li>
</ul>
</li>
<li><p>基本用法</p>
<pre><code class="lang-javascript">let add = (a, b) =&gt; {
  return a + b;
};
console.log(add(11, 22));
</code></pre>
</li>
<li><p>一个形参可省略小括号</p>
<pre><code class="lang-javascript">let add = a =&gt; {
  return a + 22;
};
console.log(add(11));
</code></pre>
</li>
<li><p>一句代码可省略大括号，并自动return执行结果</p>
<pre><code class="lang-javascript">let add = a =&gt; a + 22;
add(11);
</code></pre>
</li>
<li><p>使用例子</p>
<pre><code class="lang-javascript">let arr = [ 1, 2, 3, 4 ];
let newArr = arr.map(v =&gt; v * v);
console.log(newArr);
</code></pre>
</li>
<li><p>this固定指向上级this</p>
<pre><code class="lang-javascript">function Tab() {
  this.tabBtn = document;
  this.tabBox = document.body;
}
Tab.prototype = {
  on: function() {
      this.tabBtn.onclick = () =&gt; {
          console.log(this);
          this.tabBox.style.backgroundColor = &#39;blue&#39;;
      };
  }
};
new Tab().on();
</code></pre>
</li>
<li><p>不能作为构造函数使用</p>
<pre><code class="lang-javascript">let Person = (name, age) =&gt; {
  this.name = name;
  this.age = age;
};
let p = new Person();
</code></pre>
</li>
<li><p>不能使用arguments对象</p>
<pre><code class="lang-javascript">let fn = () =&gt; console.log(arguments);
fn(1, 2, 3);
</code></pre>
</li>
</ul>
<h2 id="-">对象</h2>
<h4 id="-">属性方法简洁表示</h4>
<ul>
<li><p>引用变量定义属性方法</p>
<pre><code class="lang-javascript">let a = 10;
let b = 20;
let fn = function(){};
let obj = { a, b, fn };
console.log(obj);
</code></pre>
</li>
<li><p>方法定义 （改造闭包缓存例子）</p>
<pre><code class="lang-javascript">let obj = {
  fn1: function() {
      console.log(&#39;传统写法&#39;);
  },
  fn2() {
      console.log(&#39;简洁写法&#39;);
  }
};
obj.fn1();
obj.fn2();
</code></pre>
</li>
</ul>
<h4 id="-">属性名支持表达式</h4>
<ul>
<li>引用变量值</li>
</ul>
<pre><code class="lang-javascript">let key = &#39;name&#39;;
let obj = {
    [ key ]: &#39;小美&#39;;
};
console.log(obj);
</code></pre>
<ul>
<li>表达式计算值</li>
</ul>
<pre><code class="lang-javascript">let key = &#39;name&#39;;
let obj = {
    [ &#39;my&#39; + key ]: &#39;小美&#39;,
};
console.log(obj);
</code></pre>
<h2 id="class-">class类</h2>
<ul>
<li>简述：<ul>
<li>提供了与传统面向对象语言相似的写法，减少其他程序员的学习门槛。</li>
<li>在功能上相比es5基本没有什么区别。</li>
</ul>
</li>
<li>特点：<ul>
<li>只能配合new关键字创建实例</li>
<li>类名不会预解析</li>
<li>类原型上的属性名可以使用表达式</li>
<li>类原型上的属性默认是不可枚举的</li>
</ul>
</li>
</ul>
<h4 id="-">语法</h4>
<ul>
<li>类的定义</li>
</ul>
<pre><code class="lang-javascript">class Person {

    constructor(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    };

    say() {
        console.log(`${ this.name }今年${ this.age }岁了`);
    };

};
var xiaoming = new Person(&#39;小明&#39;, 14, &#39;男&#39;);
xiaoming.say();
</code></pre>
<ul>
<li>静态方法</li>
</ul>
<pre><code class="lang-javascript">class Person {

    constructor() {
        Person.total++ ||  (Person.total = 1);
    };

    // 统计总人口
    static getTotal() {
        return Person.total;    
    };

};
var p1 = new Person;
var p2 = new Person;
console.log(Person.getTotal()); // 2
</code></pre>
<ul>
<li>继承1 - 子类实例使用父类实例的属性方法</li>
</ul>
<pre><code class="lang-javascript">class Animal {

    constructor(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    };

    eat() {
        console.log(&#39;都得吃啊！&#39;);
    };

};

class Person extends Animal {

    constructor(name, age, gender) {
        super(name, age, gender);
    };

    say() {
        console.log(`${ this.name }今年${ this.age }岁了`);
    };

};
var xiaoming = new Person(&#39;小明&#39;, 14, &#39;男&#39;);
xiaoming.eat();
xiaoming.say();
</code></pre>
<ul>
<li>继承2 - 子类使用父类的静态方法</li>
</ul>
<pre><code class="lang-javascript">class Animal {

    static test() {
        console.log(&#39;来自父类的静态方法&#39;);
    };

};
class Person extends Animal {};
Person.test();
</code></pre>
<h4 id="-">本质</h4>
<ul>
<li><p>类本质上是一个函数</p>
<pre><code class="lang-javascript">class Person {};
console.log(typeof Person); // function
</code></pre>
</li>
<li><p>类中的实例方法都定义在了原型中</p>
<pre><code class="lang-javascript">class Person {
  eat() {
      console.log(&#39;吃吃吃&#39;);
  };
};
console.log(Person.prototype);
</code></pre>
</li>
<li><p>类中的静态方法都定义在了自身</p>
<pre><code class="lang-javascript">class Person {
  static getTotal() {
      console.log(&#39;70亿&#39;);
  };
};
console.dir(Person);
</code></pre>
</li>
<li><p>实例继承原理（子类原型继承父类原型）</p>
</li>
</ul>
<pre><code class="lang-javascript">class Animal {
    eat() {
        console.log(&#39;都得吃啊！&#39;);
    };
};

// 子类原型 ==&gt; Animal.prototype ==&gt; Object.prototype ==&gt; null
class Person extends Animal {};
console.log(Person.prototype.__proto__ === Animal.prototype); // true

// 实例 ==&gt; Person.prototype ==&gt; Animal.prototype ==&gt; Object.prototype ==&gt; null
var xiaomei = new Person();
console.log(xiaomei.__proto__ === Person.prototype);  // true
console.log(xiaomei.__proto__.__proto__ === Animal.prototype); // true
console.log(xiaomei.__proto__.__proto__.__proto__ === Object.prototype); // true
</code></pre>
<ul>
<li>类继承原理 （子类继承父类）</li>
</ul>
<pre><code class="lang-javascript">class Animal {
    static getTotal() {
        console.log(&#39;全部有多少&#39;);
    };
};

// 子类 ==&gt; Animal ==&gt; Function.prototype ==&gt; Object.prototype ==&gt; null
class Person extends Animal {};
console.log(Person.__proto__ === Animal);  // true
console.log(Person.__proto__.__proto__ === Function.prototype); // true
console.log(Person.__proto__.__proto__.__proto__ === Object.prototype); // true
</code></pre>

          	</article>
        </div>
		</div>
  </body>
</html>
<script type="text/javascript" src="toc/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="toc/js/jquery.ztree.all-3.5.min.js"></script>
<script type="text/javascript" src="toc/js/ztree_toc.js"></script>
<script type="text/javascript" src="toc_conf.js"></script>

<SCRIPT type="text/javascript" >
<!--
$(document).ready(function(){
    var css_conf = eval(markdown_panel_style);
    $('#readme').css(css_conf)
    
    var conf = eval(jquery_ztree_toc_opts);
		$('#tree').ztree_toc(conf);
});
//-->
</SCRIPT>